package hn.cch.caffeine.configuration;

import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.CacheLoader;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.github.benmanes.caffeine.cache.LoadingCache;
import com.github.benmanes.caffeine.cache.stats.CacheStats;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.cache.CacheType;
import org.springframework.cache.CacheManager;
import org.springframework.cache.caffeine.CaffeineCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.concurrent.TimeUnit;

import static org.checkerframework.checker.units.UnitsTools.s;

@Configuration
public class CaffeineConfiguration {

    private static final Logger logger = LoggerFactory.getLogger(CaffeineConfiguration.class);


    @Bean
    public Cache<Object, Object> cache() {
        Caffeine<Object, Object> caffeine = Caffeine.newBuilder()
            .initialCapacity(3).maximumSize(3)
            .expireAfterAccess(60, TimeUnit.SECONDS);
        Cache<Object, Object> cache = caffeine.recordStats().build();
        CacheStats cacheStats = cache.stats();
        logger.info("start cache stats:{}", cacheStats.toString());
        return cache;
    }

    // @Bean
    // public CacheManager cacheManager() {
    //     CaffeineCacheManager caffeineCacheManager = new CaffeineCacheManager();
    //     Caffeine<Object, Object> caffeine = Caffeine.newBuilder()
    //         .initialCapacity(3).maximumSize(3)
    //         .expireAfterAccess(60, TimeUnit.SECONDS);
    //     caffeineCacheManager.setCaffeine(caffeine);
    //     return caffeineCacheManager;
    // }

    @Bean
    public CacheManager cacheManager() {
        CaffeineCacheManager caffeineCacheManager = new CaffeineCacheManager();
        LoadingCache<Object, Object> loadingCache = Caffeine.newBuilder().expireAfterWrite(1, TimeUnit.SECONDS)
            .build(new CacheLoader<Object, Object>() {
                @Override
                public @Nullable Object load(@NonNull Object o) throws Exception {
                    if (o instanceof String) {
                        String s = (String) o;
                        logger.info("load:{}", s);
                        return Base64.getEncoder().encodeToString(s.getBytes(StandardCharsets.UTF_8));
                    }
                    logger.info("default return blank string");
                    return "";
                }
            });
        caffeineCacheManager.registerCustomCache("loadingCache", loadingCache);
        return caffeineCacheManager;
    }


}
